export class ArrayList {
  constructor(a) {
    if (Array.isArray(a)) {
      this.data = a;
    } else {
      this.data = [];
    }
  }

  clear() {
    this.data = [];
    return this;
  }

  reverse() {
    this.data.reverse();

    return this;
  }

  getSize() {
    return this.data.length;
  }

  isEmpty() {
    return this.getSize() === 0;
  }

  last() {
    return this.data[this.data.length - 1];
  }

  asArray() {
    return this.data;
  }

  first() {
    if (this.data.length > 0) {
      return this.data[0];
    }
    return null;
  }

  get(i) {
    return this.data[i];
  }

  add(...objs) {
    this.data.push(...objs);

    return this;
  }

  find(func) {
    let result = this.data.filter(func);
    if (result.length === 0) {
      return null;
    }
    return result[0];
  }

  filter(func) {
    this.data = this.data.filter(func);
    return this;
  }

  map(func) {
    this.data = this.data.map(func);

    return this;
  }

  pop() {
    return this.removeElementAt(this.data.length - 1);
  }

  push(value) {
    this.add(value);
  }

  indexOf(obj) {
    return this.data.indexOf(obj);
  }

  remove(obj) {
    let index = this.indexOf(obj);
    if (index >= 0) {
      return this.removeElementAt(index);
    }

    return null;
  }

  insertElementAt(obj, index) {
    this.data.splice(index, 0, obj);

    return this;
  }
  removeAll(elements) {
    if (elements instanceof ArrayList) {
      elements = elements.data;
    }

    if (Array.isArray(elements)) {
      elements.forEach(e => this.remove(e));
    }

    return this;
  }

  removeElementAt(index) {
    let element = this.data[index];

    this.data.splice(index, 1);

    return element;
  }

  each(func, reverse) {
    if (typeof reverse !== "undefined" && reverse === true) {
      for (let i = this.data.length - 1; i >= 0; i--) {
        if (func(i, this.data[i]) === false) break;
      }
    } else {
      for (let i = 0; i < this.data.length; i++) {
        if (func(i, this.data[i]) === false) break;
      }
    }

    return this;
  }

  contains(obj) {
    return this.indexOf(obj) !== -1;
  }

  clone(deep) {
    let newVector = new ArrayList();

    if (deep) {
      for (let i = 0; i < this.data.length; i++) {
        newVector.data.push(this.data[i].clone());
      }
    } else {
      newVector.data = this.data.slice(0);
    }

    return newVector;
  }
}

export default ArrayList;
